const express = require('express');
const { body, query } = require('express-validator');
const locationController = require('../controllers/locationController');
const { protect, restrictTo } = require('../middleware/auth');
const rateLimit = require('express-rate-limit');

const router = express.Router();

// 限制地理位置服务请求的频率
const locationLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分钟
  max: 100, // 限制每个IP 15分钟内最多100次请求
  message: {
    status: 'error',
    message: '地理位置服务请求过于频繁，请稍后再试'
  },
  standardHeaders: true,
  legacyHeaders: false
});

// 限制推荐服务请求的频率
const recommendationLimiter = rateLimit({
  windowMs: 5 * 60 * 1000, // 5分钟
  max: 20, // 限制每个IP 5分钟内最多20次推荐请求
  message: {
    status: 'error',
    message: '推荐服务请求过于频繁，请稍后再试'
  },
  standardHeaders: true,
  legacyHeaders: false
});

// 验证规则
const geocodeValidation = [
  body('address')
    .isLength({ min: 1, max: 200 })
    .withMessage('地址长度必须在1-200个字符之间'),
  
  body('city')
    .optional()
    .isLength({ min: 1, max: 50 })
    .withMessage('城市名称长度必须在1-50个字符之间')
];

const reverseGeocodeValidation = [
  body('lng')
    .isFloat({ min: -180, max: 180 })
    .withMessage('经度必须在-180到180之间'),
  
  body('lat')
    .isFloat({ min: -90, max: 90 })
    .withMessage('纬度必须在-90到90之间')
];

const distanceValidation = [
  body('origin.lng')
    .isFloat({ min: -180, max: 180 })
    .withMessage('起点经度必须在-180到180之间'),
  
  body('origin.lat')
    .isFloat({ min: -90, max: 90 })
    .withMessage('起点纬度必须在-90到90之间'),
  
  body('destination.lng')
    .isFloat({ min: -180, max: 180 })
    .withMessage('终点经度必须在-180到180之间'),
  
  body('destination.lat')
    .isFloat({ min: -90, max: 90 })
    .withMessage('终点纬度必须在-90到90之间')
];

const routeValidation = [
  body('origin.lng')
    .isFloat({ min: -180, max: 180 })
    .withMessage('起点经度必须在-180到180之间'),
  
  body('origin.lat')
    .isFloat({ min: -90, max: 90 })
    .withMessage('起点纬度必须在-90到90之间'),
  
  body('destination.lng')
    .isFloat({ min: -180, max: 180 })
    .withMessage('终点经度必须在-180到180之间'),
  
  body('destination.lat')
    .isFloat({ min: -90, max: 90 })
    .withMessage('终点纬度必须在-90到90之间'),
  
  body('strategy')
    .optional()
    .isIn(['0', '1', '2', '3'])
    .withMessage('路线策略必须是 0(速度优先)、1(费用优先)、2(距离优先) 或 3(不走高速)')
];

const nearbyCaregiversValidation = [
  query('lng')
    .isFloat({ min: -180, max: 180 })
    .withMessage('经度必须在-180到180之间'),
  
  query('lat')
    .isFloat({ min: -90, max: 90 })
    .withMessage('纬度必须在-90到90之间'),
  
  query('radius')
    .optional()
    .isFloat({ min: 1, max: 50 })
    .withMessage('搜索半径必须在1-50公里之间'),
  
  query('skills')
    .optional()
    .custom((value) => {
      if (value) {
        const skills = value.split(',');
        const validSkills = [
          'dog_care', 'cat_care', 'bird_care', 'fish_care', 'rabbit_care',
          'reptile_care', 'small_animal_care', 'medication_administration',
          'grooming', 'training', 'walking', 'feeding', 'overnight_care',
          'emergency_care', 'senior_pet_care', 'puppy_care', 'kitten_care'
        ];
        if (!skills.every(skill => validSkills.includes(skill))) {
          throw new Error('包含无效的技能选项');
        }
      }
      return true;
    }),
  
  query('minRating')
    .optional()
    .isFloat({ min: 0, max: 5 })
    .withMessage('最低评分必须在0-5之间'),
  
  query('maxPrice')
    .optional()
    .isFloat({ min: 0 })
    .withMessage('最高价格必须是非负数'),
  
  query('emergencyService')
    .optional()
    .isBoolean()
    .withMessage('紧急服务标志必须是布尔值'),
  
  query('overnightCare')
    .optional()
    .isBoolean()
    .withMessage('过夜护理标志必须是布尔值')
];

const recommendationValidation = [
  body('location')
    .isObject()
    .withMessage('位置信息必须是对象'),
  
  body('location.address')
    .optional()
    .isLength({ min: 1, max: 200 })
    .withMessage('地址长度必须在1-200个字符之间'),
  
  body('location.city')
    .optional()
    .isLength({ min: 1, max: 50 })
    .withMessage('城市名称长度必须在1-50个字符之间'),
  
  body('location.coordinates')
    .optional()
    .isArray({ min: 2, max: 2 })
    .withMessage('坐标必须是包含经度和纬度的数组'),
  
  body('pets')
    .isArray({ min: 1 })
    .withMessage('至少需要提供一只宠物信息'),
  
  body('pets.*.species')
    .isIn(['dog', 'cat', 'bird', 'fish', 'rabbit', 'hamster', 'guinea_pig', 'reptile', 'other'])
    .withMessage('宠物种类无效'),
  
  body('serviceType')
    .isLength({ min: 1, max: 50 })
    .withMessage('服务类型长度必须在1-50个字符之间'),
  
  body('startDateTime')
    .isISO8601()
    .withMessage('开始时间格式无效'),
  
  body('endDateTime')
    .isISO8601()
    .withMessage('结束时间格式无效')
    .custom((value, { req }) => {
      const endDate = new Date(value);
      const startDate = new Date(req.body.startDateTime);
      if (endDate <= startDate) {
        throw new Error('结束时间必须晚于开始时间');
      }
      return true;
    }),
  
  body('isEmergency')
    .optional()
    .isBoolean()
    .withMessage('紧急服务标志必须是布尔值'),
  
  body('budget')
    .optional()
    .isFloat({ min: 0 })
    .withMessage('预算必须是非负数')
];

const validateAddressValidation = [
  body('address')
    .isLength({ min: 1, max: 200 })
    .withMessage('地址长度必须在1-200个字符之间'),
  
  body('city')
    .isLength({ min: 1, max: 50 })
    .withMessage('城市名称长度必须在1-50个字符之间')
];

const areaStatsValidation = [
  query('lng')
    .isFloat({ min: -180, max: 180 })
    .withMessage('经度必须在-180到180之间'),
  
  query('lat')
    .isFloat({ min: -90, max: 90 })
    .withMessage('纬度必须在-90到90之间'),
  
  query('radius')
    .optional()
    .isFloat({ min: 1, max: 50 })
    .withMessage('统计半径必须在1-50公里之间')
];

// 应用限流中间件到所有路由
router.use(locationLimiter);

// 公开路由

/**
 * @route   POST /api/location/geocode
 * @desc    地址解析为坐标
 * @access  Public
 */
router.post('/geocode', geocodeValidation, locationController.geocodeAddress);

/**
 * @route   POST /api/location/reverse-geocode
 * @desc    坐标反解析为地址
 * @access  Public
 */
router.post('/reverse-geocode', reverseGeocodeValidation, locationController.reverseGeocode);

/**
 * @route   POST /api/location/distance
 * @desc    计算两点间距离
 * @access  Public
 */
router.post('/distance', distanceValidation, locationController.calculateDistance);

/**
 * @route   POST /api/location/route
 * @desc    获取路线信息
 * @access  Public
 */
router.post('/route', routeValidation, locationController.getRouteInfo);

/**
 * @route   GET /api/location/nearby-caregivers
 * @desc    查找附近的护理员
 * @access  Public
 */
router.get('/nearby-caregivers', nearbyCaregiversValidation, locationController.findNearbyCaregivers);

/**
 * @route   GET /api/location/cities
 * @desc    获取支持的城市列表
 * @access  Public
 */
router.get('/cities', locationController.getSupportedCities);

/**
 * @route   POST /api/location/validate-address
 * @desc    验证地址有效性
 * @access  Public
 */
router.post('/validate-address', validateAddressValidation, locationController.validateAddress);

/**
 * @route   GET /api/location/service-areas
 * @desc    获取护理员服务范围内的区域
 * @access  Public
 */
router.get('/service-areas', locationController.getCaregiverServiceAreas);

/**
 * @route   GET /api/location/heatmap
 * @desc    获取热力图数据
 * @access  Public
 */
router.get('/heatmap', locationController.getHeatmapData);

/**
 * @route   GET /api/location/area-stats
 * @desc    获取区域统计信息
 * @access  Public
 */
router.get('/area-stats', areaStatsValidation, locationController.getAreaStats);

// 需要认证的路由
router.use(protect);

/**
 * @route   POST /api/location/recommend-caregivers
 * @desc    智能推荐护理员
 * @access  Private
 */
router.post('/recommend-caregivers',
  recommendationLimiter,
  recommendationValidation,
  locationController.recommendCaregivers
);

module.exports = router;